#ifndef USER_H
#define USER_H
#include <QString>
#include <QtSql>

/*! \brief User:
  This class handles user data
  from and to the database.
  The ClientHandler requests data from
  this class which uses MySQL queries to
  access the SQL database.
  Singleton Design Pattern Implementation
 */

class User
{

public:

    /*! \var static User *userInstance()
      \brief pointer to instance of the class
      */
    static User *userInstance();

    /*! addBuddy
      \brief Adds a buddy to a user's buddy list.
      \param theUser the user whose buddylist is being updated
      \param theBuddy the new buddy.
      \return Returns a true if successful, false if unsuccessful
      */
    bool addBuddy(QString theUser, QString theBuddy);

    /*! checkIfBuddies
      \brief Checks if a user has a specific user on their buddy list.
      \param userId the ID of the user
      \param buddyId the id of the buddy that might be on the user's list
      \return Returns a true if buddies, false if not buddies
      */
    bool checkIfBuddies(int userId, int buddyId);

    /*! verifyLoginInfo
      \brief verifies the username and password when the user presses the login button.
      The username and the hashed password are sent to the database and the records are checked.
      \param myUsername the username
      \param myPassword the password
      \param sid the socket ID
      \return Returns a true if login info is valid and saves the socket ID, false if incorrect or unsuccessful login info
      */
    bool verifyLoginInfo(QString myUsername, QString myPassword, int sid);

    /*! removeBuddy
      \brief Removes a user from another user's buddy list.
      \param theUser the user who is removing a buddy
      \param theBuddy the user being removed
      \return Returns true if removed successfully, false if unsuccessful
      */
    bool removeBuddy(QString theUser, QString theBuddy);

    /*! verifyEmail
      \brief For adding a new buddy via email.  Checks if a user with a specific email exists in the database.
      If such an email exists the user with that email is added to the specific user's buddy list.
      \param user the user requesting the info
      \param email the email being checked
      \return Returns true if buddy with such email exists and adds the new buddy to teh bussy list, false email DNE
      */
    bool verifyEmail(QString user, QString email);

    /*! getIdFromName
      \brief Retrieves a user's ID given their username.
      \param user the user whose ID is being returned
      \return returns the ID (int) if it exists, returns -1 if user DNE
      */
    int getIdFromName(QString user);

    /*! registerNewUser
      \brief Registers a new user. The username (and their email) is first checked to see if it is
      already taken, if not then the user is successfully registered and logs in.
      \param newUser the username
      \param newPassword the password
      \param email the email
      \param sid the socketID
      \return Returns -1 if the email is invalid, returns -1 if the username is invalid, returns -3 if it failed to register
      */
    int registerNewUser(QString newUser, QString newPassword, QString email, int sid);

    /*! getSocketId
      \brief Retrieves the socket ID of a specific user.
      \param user the user whose socket ID is being returned
      \return returns the socket ID (int) if it exists, returns -1 if DNE
      */
    int getSocketId(QString user);

    /*! setSocketId
      \brief Sets a socketID of a user.
      \param user the user
      \param sid the socket ID
      */
    void setSocketId(QString user, int sid);

    /*! removeSocketId
      \brief Removes a socketID of a user when they log out (Sets socket ID = 0 in database).
      \param user the user
      */
    void removeSocketId(QString user);

    /*! setStatus
      \brief Sets the status of a user.
      \param user the user
      \param status the status
      */
    void setStatus(QString user, QString status);

    /*! getNameFromId
      \brief Retrieves a username given their ID.
      \param id the ID of the user
      \return Returns the username if it exists, returns -1 if ID DNE
      */
    QString getNameFromId(int id);

    /*! getStatus
      \brief Retrieves the status of a specific user.
      \param user the user
      \return Returns the status
      */
    QString getStatus(QString user);

    /*! retrieveBuddies
      \brief Retrieves a user's buddies for use in the buddy list.
      \param theUser the user
      \return returns a vector containing the user's buddies
      */
    QVector <QString> retrieveBuddies(QString theUser);

    /*! retrieveStatus
      \brief Retrieves a user's status for use in the buddy list using the vecotr of buddies
       (gotten from retrieveBuddies())
      \param buddyVector the vector of buddies
      \return returns a vector statusVector containing the buddies' statuses
      */
    QVector <QString> retrieveStatus(QVector <QString> buddyVector);

private:

    /*! User
      \brief Constructor
      */
    User();

    /*! \var static User *user_p;
      \brief
      */
    static User *user_p;
};

#endif // USER_H
